package com.cindata

import com.cindata.dictionary.*
import grails.converters.JSON
import grails.gorm.transactions.Transactional
import groovy.json.JsonOutput
import org.springframework.security.access.annotation.Secured

import java.text.DecimalFormat
import java.text.SimpleDateFormat

import static org.springframework.http.HttpStatus.*

@Transactional
@Secured(['isAuthenticated()'])
class AssessController
{

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def splitMatchApiService
    def apiService
    def scoreApiService
    def springSecurityService

    def show(Assess assess)
    {
        def communityId = assess?.communityId
        if (communityId)
        {
            def user = User.findById(springSecurityService.principal.id)
            def zoneNumber = assess?.city?.zoneNumber?.toString()

            //小区详情
            def community = apiService.community(zoneNumber, communityId)
            //流动性评分
            def score = scoreApiService.communityLiquidityScore(communityId.toString())

            //查询权值
            def communityScoreWeight = CommunityScoreWeight.list().get(0)

            def closingWeight = communityScoreWeight.closingWeight
            // 成交率权重
            def listingWeight = communityScoreWeight.listingWeight
            // 挂牌率权重
            def dealAvgDayWeight = communityScoreWeight.dealAvgDayWeight
            // 成交周期权重
            def discountrateWeight = communityScoreWeight.discountrateWeight
            // 折价比权重
            def foreclosureTimesWeight = communityScoreWeight.foreclosureTimesWeight
            // 法拍次数权重

            def closingScore = 0
            def dealAvgDayScore = 0
            def listingScore = 0
            def discountrateScore = 0
            def foreclosureTimesScore = 0
            if (score?.closingScore)
            {
                //成交率评分
                closingScore = (score?.closingScore ? score?.closingScore : 0) * closingWeight
                //成交周期评分
                dealAvgDayScore = (score?.dealAverageDayScore ? score?.dealAverageDayScore : 0) * dealAvgDayWeight
                //挂牌率评分
                listingScore = (score?.listingScore ? score?.listingScore : 0) * listingWeight
                //折价比例评分（法拍计算）
                discountrateScore = (score?.discountrateScore ? score?.discountrateScore : 0) * discountrateWeight
                //法拍次数评分
                foreclosureTimesScore = (score?.foreclosureTimesScore ? score?.foreclosureTimesScore : 0) * foreclosureTimesWeight
            }

            //小区流动性总分
            def liquidityScore = closingScore + dealAvgDayScore + listingScore + discountrateScore + foreclosureTimesScore
            DecimalFormat df = new DecimalFormat("#.00");

            def closingScore1 = score?.closingScore ? score?.closingScore : 0
            def dealAverageDayScore1 = score?.dealAverageDayScore ? score?.dealAverageDayScore : 0
            def listingScore1 = score?.listingScore ? score?.listingScore : 0
            def discountrateScore1 = score?.discountrateScore ? score?.discountrateScore : 0
            def foreclosureTimesScore1 = score?.foreclosureTimesScore ? score?.foreclosureTimesScore : 0

            def scoreArr = "[" + df.format(closingScore1) + "," + df.format(dealAverageDayScore1) + "," + df.format(listingScore1) + "," + df.format(discountrateScore1) + "," + df.format(foreclosureTimesScore1) + "]"

            //查询所有押品数量
            def estateCount = Estate.executeQuery("select count(e.id) from Estate e where e.communityId = ${communityId} and e.account.id in " + Account.FilterAccountSql(user))

            //计算押品均价
            def estateList = Estate.executeQuery(" select unitPrice,loansBalance,loansEvaluateTotalPrice from Estate e where e.communityId = ${communityId} and e.account.id in " + Account.FilterAccountSql(user))

            def totalUnitPrice = 0
            def sumLoansBalance = 0
            def sumLoansEvaluatePrice = 0
            def avgUnitPrice = 0
            def avgCltv = 0
            estateList.each {
                totalUnitPrice += it[0] ? it[0] : 0
                sumLoansBalance += it[1] ? it[1]: 0
                sumLoansEvaluatePrice += it[2] ? it[2] : 0
            }

            if (estateList)
            {
                //押品均价
                avgUnitPrice = totalUnitPrice / estateList.size()
                //动态抵押率
                if (sumLoansEvaluatePrice != 0) 
                {
                    avgCltv = sumLoansBalance / sumLoansEvaluatePrice
                }
                else
                {
                    avgCltv = 0
                }
                
            }

            //成交案例列表
            def saleList = apiService.sale(zoneNumber, communityId)
            //挂牌案例列表
            def listings = apiService.listing(zoneNumber, communityId)

            respond assess, model: [liquidityScore: df.format(liquidityScore),
                communityId: communityId,
                scoreArr: scoreArr,
                community: community?.data,
                estateCount: estateCount[0],
                avgUnitPrice: avgUnitPrice,
                avgCltv: avgCltv,
                saleList: saleList['data'],
                listings: listings['data']]
        }
        else
        {
            respond assess, model: [community: null, avgUnitPrice: 0, avgCltv: 0, estateCount: 0, scoreArr: [0, 0, 0, 0, 0], liquidityScore: 0, saleList: null, listings: null]
        }
    }

    def create()
    {
        respond new Assess(params)
    }

    @Transactional
    def save(Assess assess)
    {
        if (assess == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (assess.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond assess.errors, view: 'create'
            return
        }

        assess.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'assess.label', default: 'Assess'), assess.id])
                redirect assess
            }
            '*' { respond assess, [status: CREATED] }
        }
    }

    def edit(Assess assess)
    {
        respond assess
    }

    @Transactional
    def update(Assess assess)
    {
        if (assess == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (assess.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond assess.errors, view: 'edit'
            return
        }

        assess.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'assess.label', default: 'Assess'), assess.id])
                redirect assess
            }
            '*' { respond assess, [status: OK] }
        }
    }

    @Transactional
    def delete(Assess assess)
    {

        if (assess == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        assess.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'assess.label', default: 'Assess'), assess.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'assess.label', default: 'Assess'), params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    // 评估
    def assess()
    {
        respond new Assess(params)
    }

    // 评估管理
    def history(Integer max)
    {
        def user = User.findById(springSecurityService.principal.id)
        params.max = Math.min(max ?: 10, 100)
        params.sort = "createdDate"
        params.order = "desc"
        def sql = "from Assess a where a.account in "+ Account.FilterAccountSql(user)+ " order by a."+params.sort+" "+ params.order
        def list = Assess.executeQuery(sql)
        respond list, model: [assessCount:list.size()]
    }

    // 地址差分匹配
    def splitMatch()
    {
        println "######## splitMatch ######## "

        def city = params["city"]
        def address = params["address"]

        if (!city || !Area.findByName(city))
        {
            render([status: "failed", errorMessage: '请输入正确城市！'] as JSON)
            return
        }
        if (!address)
        {
            render([status: "failed", errorMessage: '请输入房产地址！'] as JSON)
            return
        }

        def addressSplitList = splitMatchApiService.splitMatch(city, address)
        def buildYear = null
        def communityId = addressSplitList['match_community_id']
        if (communityId && communityId != "-1")
        {
            buildYear = apiService.community(Area.findByName(city)?.zoneNumber?.toString(), communityId?.toInteger())['data']?.buildYear
        }
        render([status: "success", addressSplitList: addressSplitList, buildYear: buildYear] as JSON)
    }

    // 快速评估
    @Transactional
    def propertyAssess()
    {
        println "######## propertyAssess ######## "
        println "params:" + params + "\n"

        def assessId = params['assessId']
        def em = params['em']
        def city = params['city']
        def communityId = params['communityId']
        def communityName = params['communityName']
        def address = params['address']
        def floor = params['floor'] ? params['floor']?.toInteger() : 0
        def totalFloor = params['totalFloor'] ? params['totalFloor']?.toInteger() : 0
        def area = params['area'] ? params['area']?.toDouble() : 0
        def building = params['building']
        def unit = params['unit']
        def house = params['house']
        def buildYear = params['buildYear'] ? params['buildYear']?.toInteger() : null
        def finalPrice = params['finalPrice'] ? params['finalPrice']?.toDouble() : 0
        def externalAssessPrice = params['externalAssessPrice'] ? params['externalAssessPrice']?.toDouble() : 0

        def param = [em: em,
            city: city,
            name: communityName,
            address: address,
            floor: floor,
            totalfloor: totalFloor,
            square: area,
            buildingName: building,
            unitName: unit,
            houseNumber: house,
            buildingYear: buildYear]

        println "param:" + param + "\n"

        def assess = Assess.findById(assessId)
        if (!assess)
        {
            assess = new Assess()
        }

        assess.city = City.findByName(city)
        assess.address = address
        if (communityId)
        {
            assess.communityId = communityId?.toInteger()
        }
        assess.communityName = communityName
        assess.building = building
        assess.unit = unit
        assess.house = house
        assess.floor = floor
        assess.totalFloor = totalFloor
        assess.buildYear = buildYear
        assess.area = area
        assess.finalPrice = finalPrice
        assess.externalAssessPrice = externalAssessPrice
        if (em == "1")
        {
            assess.assessType = AssessTypeDict.findByName("快速评估")
        }
        if (em == "2")
        {
            assess.assessType = AssessTypeDict.findByName("人工评估")
        }

        assess.save flush: true

        def result = apiService.evaluate(param)
        println result
        if (result.code == "0")
        {
            assess.assessUnitPrice = result?.unitprice
            assess.assessTotalPrice = result?.saleprice
            assess.assessStatus = AssessStatusDict.findByName("评估成功")

            if (result.evaluateDate)
            {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                assess.evaluateDate = format.parse(result.evaluateDate)
            }
        }
        else if (result.code == "4")
        {
            assess.assessStatus = AssessStatusDict.findByName("评估中")
            assess.evaluateCode = result?.evaluateCode
        }
        else
        {
            assess.assessStatus = AssessStatusDict.findByName("评估失败")
        }

        assess.save flush: true

        render([status: "success", result: result, assess: assess] as JSON)
    }

    def getBuilding()
    {
        println "######## getBuilding ######## "
        def city = params['city']
        def communityId = params['communityId']?.toInteger()
        def communityList = apiService.building(Area.findByName(city)?.zoneNumber?.toString(), communityId, "")
        communityList = communityList['data']
        println "communityList:" + communityList
        render([status: "success", communityList: communityList] as JSON)
    }

    def getUnit()
    {
        println "######## getUnit ######## "
        println params
        def city = params['city']
        def communityId = params['communityId']?.toInteger()
        def buildingId = params['buildingId']?.toInteger()
        def unitList = apiService.unit(Area.findByName(city)?.zoneNumber?.toString(), communityId, buildingId, "")
        unitList = unitList['data']
        println "unitList:" + unitList
        render([status: "success", unitList: unitList] as JSON)
    }

    def getHouse()
    {
        println "######## getHouse ######## "
        println params
        def city = params['city']
        def buildingId = params['buildingId']?.toInteger()
        def unitId = params['unitId']?.toInteger()
        def houseList = apiService.house(Area.findByName(city)?.zoneNumber?.toString(), buildingId, unitId, "")
        println "houseList:" + houseList
        houseList = houseList['data']
        render([status: "success", houseList: houseList] as JSON)
    }

    def searchHistory()
    {
        params.max = Math.min(params.max ? params.max.toInteger() : 10, 100)
        params.offset = params.offset ? params.offset.toInteger() : 0;

        def address = params["address"]
        def isFrequency = params["isFrequency"]
        def assessType = params["assessType"]
        def assessStatus = params["assessStatus"]
        def fullName = params["fullName"]
        def startDateStart = params["startDateStart"]
        def startDateEnd = params["startDateEnd"]

        String sql = "from Assess as a where 1=1"
        if (address)
        {
            sql += " and a.address like '%${address}%'"
        }
        if (isFrequency)
        {
            if (isFrequency == "高评倾向")
            {
                isFrequency = true
            }
            if (isFrequency == "正常")
            {
                isFrequency = false
            }
            sql += " and a.isFrequency = '${isFrequency}'"
        }
        if (assessType)
        {
            sql += " and a.assessType.name = '${assessType}'"
        }
        if (assessStatus)
        {
            sql += " and a.assessStatus.name = '${assessStatus}'"
        }
        if (fullName)
        {
            sql += " and a.user.fullName = '${fullName}'"
        }
        if (startDateStart)
        {
            //中文日期转换
            def dates = startDateStart.toString().replaceAll("[^x00-xff]", "-")
            def dates1 = dates.toString().substring(0, dates.length() - 1) + " 00:00:00"
            sql += " and to_char(a.createdDate ,'YYYY-MM-DD HH24:MI:SS') >= '${dates1}' "
        }
        if (startDateEnd)
        {
            //中文日期转换
            def datee = startDateEnd.toString().replaceAll("[^x00-xff]", "-")
            def datee1 = datee.toString().substring(0, datee.length() - 1) + " 23:59:59"
            sql += " and to_char(a.createdDate,'YYYY-MM-DD HH24:MI:SS') <='${datee1}' "
        }

        def sql1 = sql
        sql += " order by createdDate desc"

        def max = params.max
        def offset = params.offset

        def assessList = Assess.findAll(sql, [max: max, offset: offset])
        def list1 = Assess.findAll(sql1)
        def count = list1.size()

        respond assessList, model: [assessCount: count, params: params], view: 'history'
    }

    @Transactional
    def changeFrequency(Assess assess)
    {
        def isFrequency = params['isFrequency']
        if (isFrequency == 'true')
        {
            isFrequency = true
        }
        if (isFrequency == 'false')
        {
            isFrequency = false
        }
        assess.isFrequency = isFrequency
        if (assess.validate())
        {
            assess.save flush: true
        }
        else
        {
            println assess.errors
        }

        redirect action: 'show', params: [id: assess?.id]
    }

    def ifFrequency()
    {
        def flag = false
        def address = params["address"]
        def assessList = Assess.findAllByAddress(address)
        assessList?.each {
            flag = it?.isFrequency || flag
        }
        render([status: "success", flag: flag] as JSON)
    }

    @Transactional
    @Secured('permitAll')
    def assessCallback()
    {
        println "********** assessCallback *************"

        def json = request.JSON
        println json

        // 评估信息
        def assessUnitPrice = json['unitprice'] ? json['unitprice'] : 0
        def assessTotalPrice = json['saleprice'] ? json['saleprice'] : 0
        def evaluateCode = json['evaluateCode'] ? json['evaluateCode'] : null
        def evaluateDate = json['evaluateDate'] ? json['evaluateDate'] : null
        def communityId = json['communityId']
        def failReason = json['failReason']

        // 小区信息
        def info = json['info']
        def name = json['info']?.name
        def address = json['info']?.address
        def buildYear = json['info']?.buildYear
        // def buildType = json['info']?.buildType
        // def totalBuildingNum = json['info']?.totalBuildingNum
        // def totalHouseNum = json['info']?.totalHouseNum
        // def price = json['info']?.price

        def assess = Assess.findByEvaluateCode(evaluateCode)
        if (!assess)
        {
            def errors = [code: 4002, message: "评估编码未找到"]
            render JsonOutput.toJson(errors), status: 200
            return
        }
        else
        {
            assess.assessUnitPrice = assessUnitPrice
            assess.assessTotalPrice = assessTotalPrice
            if (evaluateDate)
            {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                assess.evaluateDate = format.parse(evaluateDate)
            }
            if (assessUnitPrice)
            {
                assess.assessStatus = AssessStatusDict.SUCCESS()
            }
            else
            {
                assess.assessStatus = AssessStatusDict.FAILURE()
                assess.failReason = failReason
            }

            if (!assess?.communityName && name)
            {
                assess?.communityName = name
            }
            if (!assess?.address && address)
            {
                assess?.address = address
            }
            if (!assess?.buildYear && buildYear)
            {
                assess?.buildYear = buildYear
            }
            if (!assess?.communityId && communityId != "-1")
            {
                assess?.communityId = communityId?.toInteger()
            }

            if (assess.validate())
            {
                assess.save flush: true

                def errors = [code: 4000, message: "更新成功"]
                render JsonOutput.toJson(errors), status: 200
            }
            else
            {
                println assess.errors
                def errors = [code: 4001, message: "更新失败"]
                render JsonOutput.toJson(errors), status: 200
            }
        }
    }
}